import datetime
import re

from flask import Blueprint, jsonify, request

from utils import sleep_redis
from utils.logger import get_logger
from utils.database import execute_query, execute_update, get_connection
from utils.redis_client import get_value, set_value, hash_getall, list_range
from utils.exceptions import (
    ValidationError,
    ResourceNotFoundError,
    DatabaseError,
    ExternalServiceError
)
import time
import random

# 创建模块专用的日志器
logger = get_logger("api.summary_data")

# 创建蓝图
realtime_data_bp = Blueprint('realtime_data', __name__, url_prefix='')


@realtime_data_bp.route('/get_user_real_time_data/<mac>')
def get_user_real_time_data(mac):
    result = {
        'in_time_state_data': {
            ## 当前分数
            'score': 0,
            ## 近六次实时心率数据
            'hr_data': [],
            ## 近六次实时呼吸数据
            'rr_data': [],
            ## 近六次数据对应的时间,
            'time_data': [],
            ## 当前睡眠基准心率
            'sleep_base_hr': 0,
            ## 当次睡眠呼吸频率
            'current_rr_frequency': 0,
            ## 当次深睡占比
            'deep_sleep_percent': 0,
            ## 当次睡眠HRV指数
            'current_sleep_hrv': 0,
            ## 当前血氧饱和度
            'spo2': 0,
            ## 当前使用者心率
            'hr': 0,
            ## 当前收缩压
            'sp': 0,
            ## 当前舒张压
            'dp': 0,
        },
        'code': 200,
    }

    ## 分析mac-00表得到数据，仅获取前一天的数据

    sql = "SELECT * FROM `" + str(mac) + "-00` WHERE BTM >= '" + str(datetime.datetime.now() - datetime.timedelta(days=1)) + "' ORDER BY BTM DESC"
    data = execute_query(sql)
    for d in data:
        ## 当次夜间基准心率(todo:不知道夜间基准心率是不是睡眠基准心率，下面的呼吸频率有相同问题)
        result['in_time_state_data']['sleep_base_hr'] = d['LongTimeStandardHR1']
        ## 当次夜间呼吸频率
        result['in_time_state_data']['current_rr_frequency'] = d['ThisTimeStandardRR1']
        ## 当次深睡眠占比
        result['in_time_state_data']['deep_sleep_percent'] = d['DSR']
        ## 健康指数
        result['in_time_state_data']['score'] = d['Score']
        ## 当次睡眠HRV指数
        result['in_time_state_data']['current_sleep_hrv'] = max(d['TotalCardiacEnergy'],  result['in_time_state_data']['current_sleep_hrv']);


    return result
## 心率血压数据监测接口
@realtime_data_bp.route('/get_hr_bp_data/<mac>')
def get_hr_bp_data(mac):
    result = {
        ## 收缩压数据
        'sp_data': [],
        ## 舒张压数据
        'dp_data': [],
        ## 心率过速度时常
        'hr_over_speed_time': 0,
        ## 心率过低时常
        'hr_low_time': 0,
        ## 心率超过阈值时长
        'hr_over_threshold_time': 0,
        ## 心率低于阈值时长
        'hr_low_threshold_time': 0,
        ## 日间基准心率
        'day_base_hr': 0,
        ## 夜间基准心率
        'night_base_hr': 0,
        ## 收缩压舒张压数据对应的时间
        'time_data': [],
    }
    ## 获取mac表数据
    ## 从redis获取实时数据
    now_data = sleep_redis.SC_GetNowTimeSleepDataByMac(mac)
    if now_data != None and len(now_data):
        result['sp_data'].append(now_data[11])
        result['dp_data'].append(now_data[12])
        result['time_data'].append(now_data[0])
    else:
        result['time_data'].append(datetime.datetime.now().strftime("%H:%M:%S"))

    ## 获取mac-00表数据(todo: 这一块都应该要改，除非只需要获取已经统计了的数据)
    sql = "SELECT * FROM `" + str(mac) + "-00` ORDER BY BTM DESC LIMIT 1"
    data = execute_query(sql)
    for d in data:
        ## 日间基准心率
        result['day_base_hr'] = d['LongTimeStandardHR2']
        ## 夜间基准心率
        result['night_base_hr'] = d['LongTimeStandardHR1']
        ## 心率过速时常
        result['hr_over_speed_time'] = d['HRHigh']
        ## 心率过低时常
        result['hr_low_time'] = d['HRLow']
        ## 心率超过/低于阈值时长
        result['hr_over_threshold_time'] = d['BeyondPersonal']
        result['hr_low_threshold_time'] = d['BelowPersonal']
    return {
        'in_time_heart_pressure_data': result,
        'code': 200,
    }
## 睡眠呼吸数据监测
@realtime_data_bp.route('/get_sleep_rr_data/<mac>')
def get_sleep_rr_data(mac):
    result = {
        ## 近五次呼吸频率
        'rr_data': [],
        ## 今日呼吸暂停次数
        'rr_pause_cnt': 0,
        ## 呼吸过速总时长
        'rr_overspeed_time': 0,
        ## 历史呼吸暂停次数
        'history_rr_pause_cnt': 0,
        ## 呼吸过缓总时长
        'rr_lowspeed_time': 0,
        ## 平均呼吸暂停时常
        'rr_average_pause_time': 0,
        ## 近五天呼吸暂停次数
        'rr_pause_cnt_daily': [],
        'time_data': []
    }
    now_data = sleep_redis.SC_GetNowTimeSleepDataByMac(mac)
    if now_data != None and len(now_data):
        # result['rr_data'].append(int(now_data[2]))
        result['time_data'].append(now_data[0])
    else:
        result['time_data'].append(datetime.datetime.now().strftime("%H:%M:%S"))

        ## 今日呼吸暂停次数(todo:这个是实时的呼吸暂停次数，需要修改)
        # result['rr_pause_cnt'] = d['Apnea']
        ## 呼吸过速总时长
        # result['rr_overspeed_time'] = d['RRHigh']
        # ## 呼吸过缓总时长
        # result['rr_lowspeed_time'] = d['RRLow']
        # ## 平均呼吸暂停时常
        # result['rr_average_pause_time'] = d['AAT']
    ## 从single_summary表中获取呼吸暂停总次数
    sql = "SELECT SUM(rr_pause_cnt) all_rr_pause_cnt FROM single_summary WHERE mac = '" + mac + "'"
    data = execute_query(sql)
    for d in data:
        ## 历史呼吸暂停次数
        result['history_rr_pause_cnt'] = d['all_rr_pause_cnt']

    ## 获取近五天的每天呼吸暂停次数
    sql = "SELECT summary_date, rr_pause_cnt FROM single_summary WHERE mac = '" + mac +"' AND DATE_SUB(CURDATE(), INTERVAL 5 DAY) <= DATE(summary_date) ORDER BY summary_date"
    data = execute_query(sql)

    ## 遍历前五天
    # 获取当前日期
    today = datetime.datetime.now().date()
    for i in range(5):
        if i == 0:
            ## 当天日期
            today_date = today
            ## 单独获取当天的数据
            dateEnd = today_date + datetime.timedelta(days=1)
            today_date = today_date - datetime.timedelta(hours=6)
            sql = "SELECT * FROM `" + mac + "-00` WHERE BTM >= '" + str(today_date) + "' AND BTM < '" + str(dateEnd) + "'"
            todayData = execute_query(sql)
            for d in todayData:
                ## 当日呼吸暂停次数
                result['rr_pause_cnt'] += d['Apnea']
                ## 呼吸过速总时长
                result['rr_overspeed_time'] += d['RRHigh']
                ## 呼吸过缓总时长
                result['rr_lowspeed_time'] += d['RRLow']
                ## 平均呼吸暂停时常
                result['rr_average_pause_time'] += d['AAT']
            result['rr_pause_cnt_daily'].append({
                'date': today_date.strftime("%Y-%m-%d"),
                'rr_pause_cnt': result['rr_pause_cnt']
            })
            continue
        else:
            ## 前一天日期
            today_date = today - datetime.timedelta(days=i)
        ## 当天的呼吸暂停次数
        result['rr_pause_cnt_daily'].append({
            'date': today_date.strftime("%Y-%m-%d"),
            'rr_pause_cnt': 0
        })
        for d in data:
            ## 如果当前日期等于数据库中的日期
            if today_date == d['summary_date']:
                result['rr_pause_cnt_daily'][i]['rr_pause_cnt'] = d['rr_pause_cnt']

    return {
        'data': result,
        'code': 200,
    }
## 睡眠质量数据监测
@realtime_data_bp.route('/get_sleep_quality_data/<mac>/<date>')
def get_sleep_quality_data(mac, date):
    ## 判断date是否合法
    if not re.match(r'^\d{4}-\d{2}-\d{2}$', date):
        ## 日期不合法
        return {
            'code': 400,
        }
    result = {
        ## 当次睡眠总时长
        'sleep_time': 0,
        ## 当次睡眠深度时长
        'deep_sleep_time': 0,
        ## 当次睡眠浅睡时长
        'light_sleep_time': 0,
        ## 入睡时常
        'awake_time': 0,
        ## 当次睡眠体动次数
        'body_move_cnt': 0,
        ## 夜间起床次数(todo:这个数据没有在mac-00表中)
        'get_up_cnt': 0,
        ## 睡眠周期数
        'sleep_period': 0,
        ## 快速眼动时长
        'fast_eye_move_time': 0,
        ## 睡眠状态分钟分布
        'sleep_state_minutes': [],
        'status_summary': [],
        ## 清醒时长
        'wake_time': 0,
        ## 深睡比例
        'deep_sleep_ratio': 0,
        ## 浅睡比例
        'light_sleep_ratio': 0,
        ## 眼动比例
        'eye_move_ratio': 0,
    }
    ## 将date字符串转换成date对象
    date = datetime.datetime.strptime(date, "%Y-%m-%d")
    dateEnd = date + datetime.timedelta(days=1)
    date = date - datetime.timedelta(hours=6)

    sql = "SELECT * FROM `" + mac + "-00` WHERE BTM >= '" + str(date) + "' AND BTM < '" + str(dateEnd) + "' ORDER BY BTM DESC LIMIT 1"
    data = execute_query(sql)
    for d in data:
        ## 当次睡眠总时长
        result['sleep_time'] = d['SleepTime']
        ## 当次睡眠深度时长
        result['deep_sleep_time'] = d['DeepSleep']
        ## 当次睡眠浅睡时长
        result['light_sleep_time'] = d['LightSleep']
        ## 入睡时常
        result['awake_time'] = d['FallAsleepTime']
        ## 当次睡眠体动次数
        result['body_move_cnt'] = d['BodyMovement']
        ## 快速眼动时长
        result['fast_eye_move_time'] = d['REM']
        ## 睡眠周期数
        result['sleep_period'] = d['SleepCycle']
        ## 深睡比例
        result['deep_sleep_ratio'] = d['DSR']
        ## 浅睡比例
        result['light_sleep_ratio'] = d['LSR']
        ## 眼动比例
        result['eye_move_ratio'] = d['REMR']
        ## 查询该记录对应的详细数据
        sql = "SELECT Sleep FROM `" + d['PlotDB'] + "`"
        reports = execute_query(sql)
        if len(reports) < 30:
            break
        status_summary = []
        if reports:
            current_status = reports[0]['Sleep']  # 初始状态
            start = 0  # 初始时间起点
            for i in range(1, len(reports)):
                if reports[i]['Sleep'] == 4:  # 状态未改变时
                    result['wake_time'] += 1
                if reports[i]['Sleep'] != current_status:  # 状态发生改变时
                    # 保存当前时间段
                    status_summary.append({
                        "start": start,
                        "end": i,
                        "status": current_status,
                        "percent": round((i - start) / len(reports) * 100, 2)
                    })
                    # 重置状态和起点
                    current_status = reports[i]['Sleep']
                    start = i
            # 添加最后一个时间段
            status_summary.append({
                "start": start,
                "end": len(reports),
                "status": current_status,
                "percent": round((i - start) / len(reports) * 100, 2)
            })
        result['status_summary'] = status_summary
    return {
        'data': result,
        'code': 200,
    }
## 心率变异性数据监测
@realtime_data_bp.route('/get_hr_variability_data/<mac>/<date>')
def get_hr_variability_data(mac, date):
    if not re.match(r'^\d{4}-\d{2}-\d{2}$', date):
        ## 日期不合法
        return {
            'code': 400,
        }
    result = {
        'heart_energy_trend': [],
        'heart_deceleration_trend': [],
        'neural_system_index': [],
        'heart_event_risk_index': [],
        'emotional_stress_value': 0,  # 改为列表
        'fatigue_index': 0,
        'pressure_index': [],
        'neural_excitement_index': [],
        'stomach_gut_function_index': [],
        'secretion_index': [],
        'NervousSystemIndex': [],
        'FatigueIndex': []
    }



    # 生成最近10天的日期列表（从今天往前数9天，共10天，按旧到新排列）
    today = datetime.datetime.strptime(date, "%Y-%m-%d").date()
    date_list = [today - datetime.timedelta(days=9 - i) for i in range(10)]

    # 生成查询的时间范围
    start_date = date_list[0]
    end_date = date_list[-1]
    start_datetime = datetime.datetime.combine(start_date, datetime.time.min)
    end_datetime = datetime.datetime.combine(end_date, datetime.time.max)
    start_str = start_datetime.strftime('%Y-%m-%d %H:%M:%S')
    end_str = end_datetime.strftime('%Y-%m-%d %H:%M:%S')

    # 构建SQL查询，获取这10天内每天的最新记录
    sql = f"""
            SELECT t1.* 
            FROM `{mac}-00` t1 
            INNER JOIN (
                SELECT DATE(BTM) AS day, MAX(BTM) AS max_btm 
                FROM `{mac}-00` 
                WHERE BTM BETWEEN %s AND %s
                GROUP BY day
            ) t2 ON t1.BTM = t2.max_btm 
            ORDER BY t1.BTM DESC;
        """
    data = execute_query(sql, (start_str, end_str))

    # 将数据按日期存入字典
    data_dict = {}
    for d in data:
        btm_date = d['BTM'].date()  # 假设BTM是datetime对象
        data_dict[btm_date] = d

    # 遍历日期列表，填充结果
    for date in date_list:
        if date in data_dict:
            d = data_dict[date]
            # 使用get方法避免KeyError，字段不存在时默认0
            result['heart_energy_trend'].append(d.get('TotalCardiacEnergy', 0))
            result['heart_deceleration_trend'].append(d.get('HRDF', 0))
            result['neural_system_index'].append(d.get('NervousSystemIndex', 0))
            result['heart_event_risk_index'].append(d.get('CardiovascularEventIndex', 0))

            result['pressure_index'].append(d.get('CompressionResistanceIndex', 0))
            result['neural_excitement_index'].append(d.get('NeuroexcitationIndex', 0))
            result['stomach_gut_function_index'].append(d.get('GastrointestinalIndex', 0))
            result['secretion_index'].append(d.get('EndocrineIndex', 0))
            result['NervousSystemIndex'].append(d['NervousSystemIndex'])
            result['FatigueIndex'].append(d['FatigueIndex'])
        else:
            # 填充默认值0
            result['heart_energy_trend'].append(0)
            result['heart_deceleration_trend'].append(0)
            result['neural_system_index'].append(0)
            result['heart_event_risk_index'].append(0)

            result['pressure_index'].append(0)
            result['neural_excitement_index'].append(0)
            result['stomach_gut_function_index'].append(0)
            result['secretion_index'].append(0)
            result['NervousSystemIndex'].append(0)
            result['FatigueIndex'].append(0)

    if len(data) == 0:
        return {
            'data': result,
            'code': 200,
        }
    ## 计算情绪压力
    # ## 神经系统指数
    emotion_indicator = result['NervousSystemIndex'][-1]
    # 假设 emotion_indicator 已经定义
    if emotion_indicator >= 5:
        emotion_indicator = 4.8
    deal_indicator_ok = 0
    if emotion_indicator >= 0.4 and emotion_indicator < 1.6 and deal_indicator_ok == 0:
        deal_indicator_ok = 1
        abs_val = abs(emotion_indicator - 1)
        emotion_indicator = 100 - (abs_val / 0.6) * 30
    if emotion_indicator >= 2.56 and emotion_indicator < 3.46 and deal_indicator_ok == 0:
        deal_indicator_ok = 1
        abs_val = abs(emotion_indicator - 3.01)
        emotion_indicator = 100 - (abs_val / 0.45) * 30
    if emotion_indicator >= 1.6 and emotion_indicator <= 2.56 and deal_indicator_ok == 0:
        deal_indicator_ok = 1
        abs_val = abs(emotion_indicator - 2.08)
        emotion_indicator = 40 + abs_val * (30 / 0.48)
    if emotion_indicator < 0.4 and deal_indicator_ok == 0:
        deal_indicator_ok = 1
        emotion_indicator = 40 - (emotion_indicator / 0.4) * 40
    if emotion_indicator > 3.46 and deal_indicator_ok == 0:
        deal_indicator_ok = 1
        emotion_indicator = 40 - (emotion_indicator - 3.46) * (40 / 1.54)
    # 格式化为一位小数
    emotion_indicator = float("{:.1f}".format(emotion_indicator))
    result['emotional_stress_value'] = emotion_indicator
    ## 计算疲劳指数
    tired_indicator = result['FatigueIndex'][-1]
    if tired_indicator > 100:
        tired_indicator = 96
    elif tired_indicator >= 3 and tired_indicator <= 12:
        tired_indicator = 100 - tired_indicator/9*30
    elif tired_indicator >= 12 and tired_indicator <= 49:
        tired_indicator = 70 - (tired_indicator - 12) / 37 * 30
    elif tired_indicator >= 1 and tired_indicator <3:
        tired_indicator = 70 - (tired_indicator - 1) / 2 * 30
    elif tired_indicator <1 and tired_indicator > 0:
        tired_indicator = 40 - tired_indicator * 40
    elif tired_indicator > 50:
        tired_indicator = (40 - (tired_indicator - 50)) * (40.0/50.0)
    ## 保留两位小数
    result['fatigue_index'] = round(tired_indicator,2)
    return {
        'data': result,
        'code': 200,
    }

## 获取所有老人的基本数据（房号姓名这类）
@realtime_data_bp.route('/get_user_basic_data')
def get_user_basic_data():

    ## 用户ID， MAC地址， 血压阈值， 房间号, 房间ID
    sql = "SELECT `checkin`.`name`,`user`.DataName,`room`.room_floor,`room`.room_number, `bed`.bed_name, `user`.sbp, `user`.dbp  FROM checkin LEFT JOIN `user` ON `checkin`.uid = `user`.Uid LEFT JOIN bed ON bed.bed_id = `checkin`.bed_id LEFT JOIN room ON `room`.room_id = `bed`.room_id WHERE DataName IS NOT NULL"

    userData = execute_query(sql)
    date = datetime.datetime.now().date()
    dateBefore1 = date - datetime.timedelta(days=1)
    ## 从single_summary中获取昨天的用户评分
    sql = "SELECT mac, score, summary_date FROM single_summary where summary_date = '" + dateBefore1.strftime("%Y-%m-%d") + "'"
    data = execute_query(sql)
    for d in data:
        for user in userData:
            if user['DataName'] == d['mac']:
                user['score'] = d['score']
                user['summary_date'] = d['summary_date']
                break
    return {
        'oldsterList': userData,
        'code': 200,
    }

